package tw.cuttle.handler;

import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import tw.cuttle.CuttleContext;
import tw.cuttle.bean.Action;
import tw.cuttle.bean.Process;
import tw.cuttle.bean.Template;
import tw.cuttle.exception.ActionExecutionException;
import tw.cuttle.process.MethodInvokeSupport;
import tw.cuttle.process.ProcessStrategy;


public class ActionHandler {
	private static ProcessStrategy processStrategy;
    private static Log LOGGER=LogFactory.getLog(ActionHandler.class);
    public void request(String actionId){
	execute(actionId);
	Action action=CuttleContext.getBeanHolder().getAction(actionId);
	Template template=CuttleContext.getBeanHolder().getTemplate(action.getLayout());
	try {		
		HttpServletRequest request=CuttleContext.getActionContext().getActionHelper().getRequest();
		HttpServletResponse response=CuttleContext.getActionContext().getActionHelper().getResponse();
		String view=template.getView();
		LOGGER.warn("view:"+view);
		LOGGER.warn("request:"+request);
		LOGGER.warn("response:"+response);
		LOGGER.warn("dispatcher:"+request.getRequestDispatcher(view));
	    request.getRequestDispatcher(view)
	    .forward(request, response);
	} catch (Exception e) {
	    e.printStackTrace();
	    throw new RuntimeException(e);
	}
    }
    public void ajaxRequest(String actionId){
	execute(actionId);
	evaluateView(actionId);
    }
    private void execute(String actionId){
	List<Process> processes=CuttleContext.getBeanHolder().getProcesses(actionId);
	if(processes!=null)
	for(Process process:processes){
	    CuttleContext.getActionContext().getActionHelper().getExecutedProcesses().add(process);
	    ProcessHandler processHandler=new ProcessHandler();
	    try{
	    processHandler.execute(process);
	    }catch(ActionExecutionException afe){
		break;
	    }
	}
    }
    public void preExec(String preExec) {
    	
    	try {
			processStrategy.getStrategy(CuttleContext.getBeanHolder().getSetting().getEnv().getStrategy()).preExec(preExec);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    }
    /**
     * xml sample:
     * <?xml version="1.0" encoding="UTF-8">
     * <processes>
     * <process>
     * <block id="header">
     * <![CDATA[[
     * 
     * ]]>
     * </block>
     * </process>
     * </processes>
     * @param actionId
     */
    private void evaluateView(String actionId){
	List<Process> processes=CuttleContext.getBeanHolder().getProcesses(actionId);
	try{
	CuttleContext.getActionContext().getActionHelper().getRequest().setCharacterEncoding("UTF-8");
	}catch(Exception e){
	    LOGGER.warn(e);
	}
	CuttleContext.getActionContext().getActionHelper().getResponse().setContentType("text/xml;charset=UTF-8");
	CuttleContext.getActionContext().getActionHelper().getResponse().setHeader("Cache-Control", "no-cache");
	CuttleContext.getActionContext().getActionHelper().getResponse().setDateHeader("Expires", 0);
	CuttleContext.getActionContext().getActionHelper().getResponse().setHeader("Pragma", "no-cache");
	StringBuffer xml=new StringBuffer("");
	xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
	xml.append("<processes>");
	
	for(Process process:processes){
	    if(process.getView()==null || process.getView().length()==0){
		continue;
	    }
	    xml.append("<process>");
	    xml.append("<block id=\""+process.getId()+"\">");
	    ProcessHandler processHandler=new ProcessHandler();
	    String content=processHandler.evaluateView(process);
	    xml.append("<![CDATA[");
	    xml.append(content);
	    xml.append("]]>");
	    xml.append("</block>");
	    xml.append("</process>");
	}
	
	xml.append("</processes>");
	try {
	    CuttleContext.getActionContext().getActionHelper().getResponse().getWriter().print(xml.toString());
	} catch (IOException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
    }
}
